<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>知识图谱分析</title>
  <style>
    body {
      margin: 0;
      padding: 0;
      width: 100vw;
      height: 100vh;
      overflow: hidden;
      font-family: 'Microsoft YaHei', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
      background: #fafafa;
    }

    #graph-container {
      width: 100%;
      height: 100%;
      background: white;
    }

    .link {
      fill: none;
      stroke: #666;
      stroke-width: 1.5px;
      stroke-opacity: 0.6;
      stroke-dasharray: 5,5;
      transition: all 0.3s ease;
    }

    .link:hover {
      stroke-opacity: 1;
      stroke-width: 2px;
    }

    circle {
      fill: #fff;
      stroke: #2196F3;
      stroke-width: 2px;
      transition: all 0.3s ease;
      cursor: pointer;
    }

    circle:hover {
      stroke-width: 3px;
      filter: drop-shadow(0 0 3px rgba(33, 150, 243, 0.3));
    }

    text {
      font: 13px 'Microsoft YaHei';
      pointer-events: none;
      text-shadow: 
        0 1px 0 #fff,
        1px 0 0 #fff,
        0 -1px 0 #fff,
        -1px 0 0 #fff;
    }

    .linetext {
      font-size: 12px;
      fill: #666;
      text-anchor: middle;
    }

    /* 节点类型样式 */
    .node-root circle {
      fill: #E3F2FD;
      stroke: #2196F3;
    }

    .node-level-1 circle {
      fill: #E8F5E9;
      stroke: #4CAF50;
    }

    .node-level-2 circle {
      fill: #FFF3E0;
      stroke: #FF9800;
    }

    .node-level-3 circle {
      fill: #FCE4EC;
      stroke: #E91E63;
    }

    /* 加载动画 */
    .loading {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      font-size: 16px;
      color: #666;
    }

    /* 工具提示 */
    .tooltip {
      position: absolute;
      padding: 8px 12px;
      background: rgba(0, 0, 0, 0.8);
      color: white;
      border-radius: 4px;
      font-size: 12px;
      pointer-events: none;
      opacity: 0;
      transition: opacity 0.3s;
    }
  </style>
</head>
<body>
  <div id="graph-container"></div>
  <div class="loading">正在加载知识图谱...</div>
  <div class="tooltip"></div>

  <script src="https://d3js.org/d3.v3.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  <script>
    // 获取容器尺寸
    const container = document.getElementById('graph-container');
    const width = container.clientWidth;
    const height = container.clientHeight;

    // 创建SVG
    const svg = d3.select("#graph-container")
      .append("svg")
      .attr("width", width)
      .attr("height", height);

    // 添加一个 g 元素作为所有元素的容器
    const g = svg.append("g");

    // 创建力导向图布局
    const force = d3.layout.force()
      .size([width, height])
      .linkDistance(150)
      .charge(-1000)
      .gravity(0.1);

    // 添加缩放和平移功能
    const zoom = d3.behavior.zoom()
      .scaleExtent([0.1, 3])
      .on("zoom", function() {
        g.attr("transform", 
          "translate(" + d3.event.translate + ")" +
          "scale(" + d3.event.scale + ")"
        );
      });

    svg.call(zoom);

    // 添加箭头定义
    g.append("defs").selectAll("marker")
      .data(["end"])
      .enter().append("marker")
      .attr("id", String)
      .attr("viewBox", "0 -5 10 10")
      .attr("refX", 25)
      .attr("refY", 0)
      .attr("markerWidth", 6)
      .attr("markerHeight", 6)
      .attr("orient", "auto")
      .append("path")
      .attr("d", "M0,-5L10,0L0,5")
      .style("fill", "#666");

    // 修改数据处理部分
    const xuanran = JSON.parse(localStorage.getItem("渲染"));
    const links = [];
    const nodes = [];

    // 创建根节点
    nodes.push({
      id: "故障光缆段",
      name: "故障光缆段",
      level: 0
    });

    // 处理数据创建节点和连接
    if (xuanran && Array.isArray(xuanran)) {
      const nodeMap = new Map();
      nodeMap.set("故障光缆段", 0);

      xuanran.forEach(item => {
        // 处理光缆段节点
        if (item.所属光缆段 && !nodeMap.has(item.所属光缆段)) {
          nodes.push({
            id: item.所属光缆段,
            name: item.所属光缆段,
            level: 1
          });
          nodeMap.set(item.所属光缆段, nodes.length - 1);
          links.push({
            source: 0,
            target: nodes.length - 1,
            relation: "所属光缆段"
          });

          // 从光缆-光路-业务数组中获取详细信息
          if (item['光缆-光路-业务'] && Array.isArray(item['光缆-光路-业务'])) {
            // 获取该光缆段下的所有光路
            const uniquePaths = [...new Set(item['光缆-光路-业务'].map(detail => detail.对应光路))];
            
            uniquePaths.forEach(path => {
              if (path && !nodeMap.has(path)) {
                nodes.push({
                  id: path,
                  name: path,
                  level: 2
                });
                const pathIndex = nodes.length - 1;
                nodeMap.set(path, pathIndex);
                
                // 连接光缆段到光路
                links.push({
                  source: nodeMap.get(item.所属光缆段),
                  target: pathIndex,
                  relation: "对应光路"
                });

                // 获取该光路下的所有业务
                const relatedServices = item['光缆-光路-业务']
                  .filter(detail => detail.对应光路 === path && detail.yw_名称)
                  .map(detail => detail.yw_名称);

                // 添加业务节点
                [...new Set(relatedServices)].forEach(service => {
                  if (!nodeMap.has(service)) {
                    nodes.push({
                      id: service,
                      name: service,
                      level: 3
                    });
                    const serviceIndex = nodes.length - 1;
                    nodeMap.set(service, serviceIndex);
                    
                    // 连接光路到业务
                    links.push({
                      source: pathIndex,
                      target: serviceIndex,
                      relation: "业务名称"
                    });
                  }
                });
              }
            });
          }
        }
      });
    }

    // 更新力导向图参数
    force
      .linkDistance(200)  // 增加节点间距
      .charge(-2000)      // 增加斥力
      .gravity(0.15)      // 调整重力
      .nodes(nodes)
      .links(links)
      .start();

    // 创建连线
    const link = g.selectAll(".link")
      .data(links)
      .enter()
      .append("g")
      .attr("class", "link-group");

    link.append("line")
      .attr("class", "link")
      .attr("marker-end", "url(#end)");

    link.append("text")
      .attr("class", "linetext")
      .text(d => d.relation);

    // 创建节点
    const node = g.selectAll(".node")
      .data(nodes)
      .enter()
      .append("g")
      .attr("class", d => `node node-level-${d.level}`)
      .call(force.drag);

    node.append("circle")
      .attr("r", 12);

    node.append("text")
      .attr("dx", 15)
      .attr("dy", ".35em")
      .text(d => d.name);

    // 添加工具提示
    const tooltip = d3.select(".tooltip");

    node.on("mouseover", function(d) {
      tooltip.style("opacity", 1)
        .html(getNodeInfo(d))
        .style("left", (d3.event.pageX + 10) + "px")
        .style("top", (d3.event.pageY - 10) + "px");
    })
    .on("mouseout", function() {
      tooltip.style("opacity", 0);
    });

    // 更新位置
    force.on("tick", function() {
      link.selectAll("line")
        .attr("x1", d => d.source.x)
        .attr("y1", d => d.source.y)
        .attr("x2", d => {
          const dx = d.target.x - d.source.x;
          const dy = d.target.y - d.source.y;
          const dr = Math.sqrt(dx * dx + dy * dy);
          return d.target.x - (dx * 12) / dr;
        })
        .attr("y2", d => {
          const dx = d.target.x - d.source.x;
          const dy = d.target.y - d.source.y;
          const dr = Math.sqrt(dx * dx + dy * dy);
          return d.target.y - (dy * 12) / dr;
        });

      link.selectAll("text")
        .attr("x", d => (d.source.x + d.target.x) / 2)
        .attr("y", d => (d.source.y + d.target.y) / 2 - 10);

      node.attr("transform", d => `translate(${d.x},${d.y})`);
    });

    // 移除加载提示
    d3.select(".loading").remove();

    function getNodeInfo(d) {
      return `
        <div>
          <strong>${d.name}</strong><br>
          <small>层级: ${d.level}</small>
        </div>
      `;
    }
  </script>
</body>
</html>
